package montecarlosinglethread;


import java.util.Random;

public class MonteCarlo {

	
	public static double[] main(String CallPutFlag,
			double S, double X, double T, double r, double b, double v,
			int nSteps, int nSimulations) {
		//final long start = System.nanoTime();

		final double value[] = MonteCarloStandardOption(CallPutFlag, S, X,
				T, r, b, v, nSteps, nSimulations);
		

		//final long end = System.nanoTime();

		System.out.println("Time of execution : " + value[1]);
		System.out.println("The computed value is : " + value[0]);
		
		return value;
	}
	
	
	

	public static double[] MonteCarloStandardOption(String CallPutFlag,
			double S, double X, double T, double r, double b, double v,
			int nSteps, int nSimulations) {

		/*System.out.println("At the begining : CallPut = " + CallPutFlag);
		System.out.println("At the begining : S = " + S);
		System.out.println("At the begining : X = " + X);
		System.out.println("At the begining : T = " + T);
		System.out.println("At the begining : r = " + r);
		System.out.println("At the begining : b = " + b);
		System.out.println("At the begining : v = " + v);
		System.out.println("At the begining : nsteps = " + nSteps);*/
		double finish[] = new double[2];
		double dt;
		double St = 0;
		double Sum = 0;
		double Drift;
		double vSqrdt;
		int j, k, z = 0;
		Random random = new Random();

		dt = T / nSteps;
		Drift = (b - Math.pow(v, 2) / 2) * dt;
		vSqrdt = v * Math.sqrt(dt);

		if (CallPutFlag == "Call") {
			z = 1;
		} else if (CallPutFlag == "Put") {
			z = -1;
		}
		
		/************************ Clock Start **********************/
		final long start = System.nanoTime();

		for (j = 1; j < nSimulations; j++) {
			St = S;
			//System.out.println("Then St = " + St);
			

			for (k = 1; k < nSteps; k++) {
				St = St * Math.exp(Drift + vSqrdt * random.nextGaussian());
				//System.out.println("And St = " + St);
			}

			Sum = Sum + Math.max(z * (St - X), 0);
			//System.out.println("St : " + St + " // X : " + X);
			//System.out.println("Sum : " + Sum);
		}

		finish[0] = Math.exp(-r * T) * (Sum / nSimulations);  // Put the total in finish 0
		//System.out.println("r : " + r + " // T : " + T);
		//System.out.println("Sum : " + Sum + " // nSimulations : " + nSimulations);
		
		final long end = System.nanoTime();
		/************************ Clock End ************************/
		
		finish[1] = (end - start) / 1.0e9; // Put the time in finish 1
		
		System.out.println("finish 0 : " + finish[0] + " // finish 1 : " + finish[1]);
		 
		return finish;

	}

}